package com.cml.domain.service;

import com.alibaba.fastjson.JSONObject;
import com.cml.common.constant.MessageType;
import com.cml.common.context.ServerContext;
import com.cml.common.dto.entity.SoltMetadata;
import com.cml.common.util.SoltMathUtil;
import com.cml.domain.entity.DefaultMessage;
import com.cml.domain.entity.ServerNode;
import com.cml.infrastructure.MessageQueueManager;

import java.util.Map;

/**
 * 姓名：陈茂林
 * 时间：2023/11/21 8:37
 * 描述：
 */
public class SoltManagerService extends AbsractSoltManagerService{
    private ServiceInstanceManagerService serviceInstanceManagerService = new ServiceInstanceManagerService();

    public SoltManagerService(ServerContext serverContext,SoltContextManagerService soltContextManagerService) {
        super(serverContext,soltContextManagerService);
    }

    @Override
    protected void allocateSolt() {
        this.calculateSlotsAllocation();
    }

    @Override
    protected Integer getSoltMetadataSynType() {
        return MessageType.SOLT_METADATA_MESSAGE;
    }

    @Override
    protected Integer getSendServerNodeSoltMessageType() {
        return MessageType.CUR_SERVER_NODE_SOLT_METADATA_MESSAGE;
    }

    @Override
    protected void waitGetCurServerNodeSoltMeatadata() throws InterruptedException {
        DefaultMessage defaultMessage = (DefaultMessage) MessageQueueManager.takeCurServerNodeSoltMetadataMessage();
        this.setCurServerNodeSoltMetadata(JSONObject.parseObject(defaultMessage.getDefaultMessage(),SoltMetadata.class));
    }

    @Override
    protected ServiceInstanceManagerService doGetServiceInstanceManagerService() {
        return serviceInstanceManagerService;
    }

    private void calculateSlotsAllocation() {
        Map<Integer, ServerNode> allRemoteServerNode = this.getNetworkManager().getAllRemoteServerNode();
        int totalServerNodeNum =  allRemoteServerNode.size();
        logger.info("----------------开始初始化槽位------------------");
        logger.info("当前所有serverNode数为:"+totalServerNodeNum);
        logger.info("当前总槽位数为:"+ SoltMathUtil.SLOTS_COUNT);
        // 计算平均每个master节点分配到几个slot槽位
        int slotsPerMasterNode = SoltMathUtil.SLOTS_COUNT / totalServerNodeNum;
        // 计算controller分配到的slot槽位是多少个，如果有多余就加上
        int remainSlotsCount = SoltMathUtil.SLOTS_COUNT - slotsPerMasterNode * totalServerNodeNum;

        // 初始化每个master节点对应的槽位的数量
        Integer nextStartSlot = 0;


        for (Integer serverNodeId: allRemoteServerNode.keySet()){
            SoltMetadata soltMetadata=new SoltMetadata();
            soltMetadata.setServerNodeId(serverNodeId);
            soltMetadata.setStartSlot(nextStartSlot+1);

            nextStartSlot = nextStartSlot+slotsPerMasterNode;
            soltMetadata.setEndSlot(nextStartSlot);
            this.getSlotsAllocation().add(soltMetadata);
        }

        SoltMetadata endSoltMetadata = this.getSlotsAllocation().get(this.getSlotsAllocation().size()-1);
        endSoltMetadata.setEndSlot(endSoltMetadata.getEndSlot()+remainSlotsCount);

        logger.info(this.getSlotsAllocation());
        logger.info("----------------初始化槽位结束------------------");
    }
}
